Micron Document
🎖️GitЯра🎖️

Node / meshtastic / Meshtastic-Android / files / .specify / scripts / bash / check-prerequisites.sh

Displaying Raw • Download

.specify/scripts/bash/check-prerequisites.sh 65a1f5ce4d0e4b8eafcd0bbfccafd41dc6ee888a (65a1f5ce) Text, 6.16 KB

T8b949e#!/usr/bin/env bash

T8b949e# Consolidated prerequisite checking script
T8b949e#
T8b949e# This script provides unified prerequisite checking for Spec-Driven Development workflow.
T8b949e# It replaces the functionality previously spread across multiple scripts.
T8b949e#
T8b949e# Usage: ./check-prerequisites.sh [OPTIONS]
T8b949e#
T8b949e# OPTIONS:
T8b949e# --json Output in JSON format
T8b949e# --require-tasks Require tasks.md to exist (for implementation phase)
T8b949e# --include-tasks Include tasks.md in AVAILABLE_DOCS list
T8b949e# --paths-only Only output path variables (no validation)
T8b949e# --help, -h Show help message
T8b949e#
T8b949e# OUTPUTS:
T8b949e# JSON mode: {"FEATURE_DIR":"...", "AVAILABLE_DOCS":["..."]}
T8b949e# Text mode: FEATURE_DIR:... \n AVAILABLE_DOCS: \n ✓/✗ file.md
T8b949e# Paths only: REPO_ROOT: ... \n BRANCH: ... \n FEATURE_DIR: ... etc.

Tffa657set -e

T8b949e# Parse command line arguments
Te6edf3JSON_MODETff7b72=Tffa657false
Te6edf3REQUIRE_TASKSTff7b72=Tffa657false
Te6edf3INCLUDE_TASKSTff7b72=Tffa657false
Te6edf3PATHS_ONLYTff7b72=Tffa657false

Tff7b72for arg Tff7b72in Ta5d6ff"Te6edf3$@Ta5d6ff"Tb4b4b4; Tff7b72do
Tff7b72case Ta5d6ff"Te6edf3$argTa5d6ff" Tff7b72in
--jsonTff7b72)
Te6edf3JSON_MODETff7b72=Tffa657true
Tb4b4b4;Tb4b4b4;
--require-tasksTff7b72)
Te6edf3REQUIRE_TASKSTff7b72=Tffa657true
Tb4b4b4;Tb4b4b4;
--include-tasksTff7b72)
Te6edf3INCLUDE_TASKSTff7b72=Tffa657true
Tb4b4b4;Tb4b4b4;
--paths-onlyTff7b72)
Te6edf3PATHS_ONLYTff7b72=Tffa657true
Tb4b4b4;Tb4b4b4;
--helpTb4b4b4|-hTff7b72)
cat Ta5d6ff<< 'EOF'
Usage: check-prerequisites.sh [OPTIONS]

Consolidated prerequisite checking for Spec-Driven Development workflow.

OPTIONS:
--json Output in JSON format
--require-tasks Require tasks.md to exist (for implementation phase)
--include-tasks Include tasks.md in AVAILABLE_DOCS list
--paths-only Only output path variables (no prerequisite validation)
--help, -h Show this help message

EXAMPLES:
# Check task prerequisites (plan.md required)
./check-prerequisites.sh --json
# Check implementation prerequisites (plan.md + tasks.md required)
./check-prerequisites.sh --json --require-tasks --include-tasks
# Get feature paths only (no validation)
./check-prerequisites.sh --paths-only
EOF
Tffa657exit T79c0ff0
Tb4b4b4;Tb4b4b4;
*Tff7b72)
Tffa657echo Ta5d6ff"Ta5d6ffERROR: Unknown option 'Te6edf3$argTa5d6ff'. Use --help for usage information.Ta5d6ff" >Tb4b4b4&T79c0ff2
Tffa657exit T79c0ff1
Tb4b4b4;Tb4b4b4;
Tff7b72esac
Tff7b72done

T8b949e# Source common functions
Te6edf3SCRIPT_DIRTff7b72=Ta5d6ff"Tff7b72$(Te6edf3CDPATHTff7b72=Ta5d6ff"" Tffa657cd Ta5d6ff"Tff7b72$(dirname Ta5d6ff"Tffd700${Te6edf3BASH_SOURCETb4b4b4[0]Tffd700}Ta5d6ff"Tff7b72)Ta5d6ff" Tff7b72&& Tffa657pwdTff7b72)Ta5d6ff"
Tffa657source Ta5d6ff"Te6edf3$SCRIPT_DIRTa5d6ff/common.shTa5d6ff"

T8b949e# Get feature paths and validate branch
Te6edf3_paths_outputTff7b72=Tff7b72$(get_feature_pathsTff7b72) Tff7b72|| Tff7b72{ Tffa657echo Ta5d6ff"ERROR: Failed to resolve feature paths" >Tb4b4b4&T79c0ff2Tb4b4b4; Tffa657exit T79c0ff1Tb4b4b4; Tff7b72}
Tffa657eval Ta5d6ff"Te6edf3$_paths_outputTa5d6ff"
Tffa657unset _paths_output
check_feature_branch Ta5d6ff"Te6edf3$CURRENT_BRANCHTa5d6ff" Ta5d6ff"Te6edf3$HAS_GITTa5d6ff" Tff7b72|| Tffa657exit T79c0ff1

T8b949e# If paths-only mode, output paths and exit (support JSON + paths-only combined)
Tff7b72if Te6edf3$PATHS_ONLYTb4b4b4; Tff7b72then
Tff7b72if Te6edf3$JSON_MODETb4b4b4; Tff7b72then
T8b949e# Minimal JSON paths payload (no validation performed)
Tff7b72if has_jqTb4b4b4; Tff7b72then
jq -cn Tffea00\
--arg repo_root Ta5d6ff"Te6edf3$REPO_ROOTTa5d6ff" Tffea00\
--arg branch Ta5d6ff"Te6edf3$CURRENT_BRANCHTa5d6ff" Tffea00\
--arg feature_dir Ta5d6ff"Te6edf3$FEATURE_DIRTa5d6ff" Tffea00\
--arg feature_spec Ta5d6ff"Te6edf3$FEATURE_SPECTa5d6ff" Tffea00\
--arg impl_plan Ta5d6ff"Te6edf3$IMPL_PLANTa5d6ff" Tffea00\
--arg tasks Ta5d6ff"Te6edf3$TASKSTa5d6ff" Tffea00\
Ta5d6ff'{REPO_ROOT:$repo_root,BRANCH:$branch,FEATURE_DIR:$feature_dir,FEATURE_SPEC:$feature_spec,IMPL_PLAN:$impl_plan,TASKS:$tasks}'
Tff7b72else
Tffa657printf Ta5d6ff'{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS":"%s"}\n' Tffea00\
Ta5d6ff"Tff7b72$(json_escape Ta5d6ff"Te6edf3$REPO_ROOTTa5d6ff"Tff7b72)Ta5d6ff" Ta5d6ff"Tff7b72$(json_escape Ta5d6ff"Te6edf3$CURRENT_BRANCHTa5d6ff"Tff7b72)Ta5d6ff" Ta5d6ff"Tff7b72$(json_escape Ta5d6ff"Te6edf3$FEATURE_DIRTa5d6ff"Tff7b72)Ta5d6ff" Ta5d6ff"Tff7b72$(json_escape Ta5d6ff"Te6edf3$FEATURE_SPECTa5d6ff"Tff7b72)Ta5d6ff" Ta5d6ff"Tff7b72$(json_escape Ta5d6ff"Te6edf3$IMPL_PLANTa5d6ff"Tff7b72)Ta5d6ff" Ta5d6ff"Tff7b72$(json_escape Ta5d6ff"Te6edf3$TASKSTa5d6ff"Tff7b72)Ta5d6ff"
Tff7b72fi
Tff7b72else
Tffa657echo Ta5d6ff"Ta5d6ffREPO_ROOT: Te6edf3$REPO_ROOTTa5d6ff"
Tffa657echo Ta5d6ff"Ta5d6ffBRANCH: Te6edf3$CURRENT_BRANCHTa5d6ff"
Tffa657echo Ta5d6ff"Ta5d6ffFEATURE_DIR: Te6edf3$FEATURE_DIRTa5d6ff"
Tffa657echo Ta5d6ff"Ta5d6ffFEATURE_SPEC: Te6edf3$FEATURE_SPECTa5d6ff"
Tffa657echo Ta5d6ff"Ta5d6ffIMPL_PLAN: Te6edf3$IMPL_PLANTa5d6ff"
Tffa657echo Ta5d6ff"Ta5d6ffTASKS: Te6edf3$TASKSTa5d6ff"
Tff7b72fi
Tffa657exit T79c0ff0
Tff7b72fi

T8b949e# Validate required directories and files
Tff7b72if Tff7b72[Tff7b72[ ! -d Ta5d6ff"Te6edf3$FEATURE_DIRTa5d6ff" Tff7b72]Tff7b72]Tb4b4b4; Tff7b72then
Tffa657echo Ta5d6ff"Ta5d6ffERROR: Feature directory not found: Te6edf3$FEATURE_DIRTa5d6ff" >Tb4b4b4&T79c0ff2
Tffa657echo Ta5d6ff"Run /speckit.specify first to create the feature structure." >Tb4b4b4&T79c0ff2
Tffa657exit T79c0ff1
Tff7b72fi

Tff7b72if Tff7b72[Tff7b72[ ! -f Ta5d6ff"Te6edf3$IMPL_PLANTa5d6ff" Tff7b72]Tff7b72]Tb4b4b4; Tff7b72then
Tffa657echo Ta5d6ff"Ta5d6ffERROR: plan.md not found in Te6edf3$FEATURE_DIRTa5d6ff" >Tb4b4b4&T79c0ff2
Tffa657echo Ta5d6ff"Run /speckit.plan first to create the implementation plan." >Tb4b4b4&T79c0ff2
Tffa657exit T79c0ff1
Tff7b72fi

T8b949e# Check for tasks.md if required
Tff7b72if Te6edf3$REQUIRE_TASKS Tff7b72&& Tff7b72[Tff7b72[ ! -f Ta5d6ff"Te6edf3$TASKSTa5d6ff" Tff7b72]Tff7b72]Tb4b4b4; Tff7b72then
Tffa657echo Ta5d6ff"Ta5d6ffERROR: tasks.md not found in Te6edf3$FEATURE_DIRTa5d6ff" >Tb4b4b4&T79c0ff2
Tffa657echo Ta5d6ff"Run /speckit.tasks first to create the task list." >Tb4b4b4&T79c0ff2
Tffa657exit T79c0ff1
Tff7b72fi

T8b949e# Build list of available documents
Te6edf3docsTff7b72=Tff7b72(Tff7b72)

T8b949e# Always check these optional docs
Tff7b72[Tff7b72[ -f Ta5d6ff"Te6edf3$RESEARCHTa5d6ff" Tff7b72]Tff7b72] Tff7b72&& Te6edf3docsTff7b72+=Tff7b72(Ta5d6ff"research.md"Tff7b72)
Tff7b72[Tff7b72[ -f Ta5d6ff"Te6edf3$DATA_MODELTa5d6ff" Tff7b72]Tff7b72] Tff7b72&& Te6edf3docsTff7b72+=Tff7b72(Ta5d6ff"data-model.md"Tff7b72)

T8b949e# Check contracts directory (only if it exists and has files)
Tff7b72if Tff7b72[Tff7b72[ -d Ta5d6ff"Te6edf3$CONTRACTS_DIRTa5d6ff" Tff7b72]Tff7b72] Tff7b72&& Tff7b72[Tff7b72[ -n Ta5d6ff"Tff7b72$(ls -A Ta5d6ff"Te6edf3$CONTRACTS_DIRTa5d6ff" T79c0ff2>/dev/nullTff7b72)Ta5d6ff" Tff7b72]Tff7b72]Tb4b4b4; Tff7b72then
Te6edf3docsTff7b72+=Tff7b72(Ta5d6ff"contracts/"Tff7b72)
Tff7b72fi

Tff7b72[Tff7b72[ -f Ta5d6ff"Te6edf3$QUICKSTARTTa5d6ff" Tff7b72]Tff7b72] Tff7b72&& Te6edf3docsTff7b72+=Tff7b72(Ta5d6ff"quickstart.md"Tff7b72)

T8b949e# Include tasks.md if requested and it exists
Tff7b72if Te6edf3$INCLUDE_TASKS Tff7b72&& Tff7b72[Tff7b72[ -f Ta5d6ff"Te6edf3$TASKSTa5d6ff" Tff7b72]Tff7b72]Tb4b4b4; Tff7b72then
Te6edf3docsTff7b72+=Tff7b72(Ta5d6ff"tasks.md"Tff7b72)
Tff7b72fi

T8b949e# Output results
Tff7b72if Te6edf3$JSON_MODETb4b4b4; Tff7b72then
T8b949e# Build JSON array of documents
Tff7b72if has_jqTb4b4b4; Tff7b72then
Tff7b72if Tff7b72[Tff7b72[ Tffd700${#Te6edf3docsTb4b4b4[@]Tffd700} -eq T79c0ff0 Tff7b72]Tff7b72]Tb4b4b4; Tff7b72then
Te6edf3json_docsTff7b72=Ta5d6ff"[]"
Tff7b72else
Te6edf3json_docsTff7b72=Tff7b72$(Tffa657printf Ta5d6ff'%s\n' Ta5d6ff"Tffd700${Te6edf3docsTb4b4b4[@]Tffd700}Ta5d6ff" Tb4b4b4| jq -R . Tb4b4b4| jq -s .Tff7b72)
Tff7b72fi
jq -cn Tffea00\
--arg feature_dir Ta5d6ff"Te6edf3$FEATURE_DIRTa5d6ff" Tffea00\
--argjson docs Ta5d6ff"Te6edf3$json_docsTa5d6ff" Tffea00\
Ta5d6ff'{FEATURE_DIR:$feature_dir,AVAILABLE_DOCS:$docs}'
Tff7b72else
Tff7b72if Tff7b72[Tff7b72[ Tffd700${#Te6edf3docsTb4b4b4[@]Tffd700} -eq T79c0ff0 Tff7b72]Tff7b72]Tb4b4b4; Tff7b72then
Te6edf3json_docsTff7b72=Ta5d6ff"[]"
Tff7b72else
Te6edf3json_docsTff7b72=Tff7b72$(Tff7b72for d Tff7b72in Ta5d6ff"Tffd700${Te6edf3docsTb4b4b4[@]Tffd700}Ta5d6ff"Tb4b4b4; Tff7b72do Tffa657printf Ta5d6ff'"%s",' Ta5d6ff"Tff7b72$(json_escape Ta5d6ff"Te6edf3$dTa5d6ff"Tff7b72)Ta5d6ff"Tb4b4b4; Tff7b72doneTff7b72)
Te6edf3json_docsTff7b72=Ta5d6ff"Ta5d6ff[Tffd700${Te6edf3json_docsTb4b4b4%,Tffd700}Ta5d6ff]Ta5d6ff"
Tff7b72fi
Tffa657printf Ta5d6ff'{"FEATURE_DIR":"%s","AVAILABLE_DOCS":%s}\n' Ta5d6ff"Tff7b72$(json_escape Ta5d6ff"Te6edf3$FEATURE_DIRTa5d6ff"Tff7b72)Ta5d6ff" Ta5d6ff"Te6edf3$json_docsTa5d6ff"
Tff7b72fi
Tff7b72else
T8b949e# Text output
Tffa657echo Ta5d6ff"Ta5d6ffFEATURE_DIR:Te6edf3$FEATURE_DIRTa5d6ff"
Tffa657echo Ta5d6ff"AVAILABLE_DOCS:"
T8b949e# Show status of each potential document
check_file Ta5d6ff"Te6edf3$RESEARCHTa5d6ff" Ta5d6ff"research.md"
check_file Ta5d6ff"Te6edf3$DATA_MODELTa5d6ff" Ta5d6ff"data-model.md"
check_dir Ta5d6ff"Te6edf3$CONTRACTS_DIRTa5d6ff" Ta5d6ff"contracts/"
check_file Ta5d6ff"Te6edf3$QUICKSTARTTa5d6ff" Ta5d6ff"quickstart.md"
Tff7b72if Te6edf3$INCLUDE_TASKSTb4b4b4; Tff7b72then
check_file Ta5d6ff"Te6edf3$TASKSTa5d6ff" Ta5d6ff"tasks.md"
Tff7b72fi
Tff7b72fi

Served by rngit 1.5.2 - Generated in 0.13s